﻿/* Author - Anshu Dutta - anshu.dutta@gmail.com
 * This source code is governed by terms and condition of Microsoft Public License (Ms-PL). 
 * Copyright (C)  2011 Anshu Dutta. anshu.dutta@gmail.com
 */
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Text;
using System.Net;
using RssNewsFeeder.Lib.ErrorHandler;

namespace RssNewsFeeder.Lib.Model.Data
{
    public class DataAccessLayer:IDisposable
    {
        private static DataAccessLayer _dataAccessLayer;
       

        static readonly object padlock = new object();
        private DataAccessLayer() { }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <returns></returns>
        public static DataAccessLayer CreateInstance()
        {
            try
            {
                // This implementation is thread-safe. The thread takes out a lock on a shared object, and then checks whether 
                // or not the instance has been created before creating the instance. 
                // This takes care of the memory barrier issue (as locking makes sure that all reads occur logically after the
                // lock acquire, and unlocking makes sure that all writes occur logically before the lock release) and ensures 
                // that only one thread will create an instance 
                
                lock (padlock)
                {
                    if (_dataAccessLayer == null)
                    {
                        _dataAccessLayer = new DataAccessLayer();
                    }
                    return _dataAccessLayer;
                }
                
            }
            catch (Exception ex)
            {
                Error.LogError(ex.Message.ToString());
                return null;
            }
        }

        /// <summary>
        /// Get feed URL
        /// </summary>
        /// <param name="Company"></param>
        /// <param name="Category"></param>
        /// <returns>Rss feed URL</returns>
        public string GetFeedURL(string Company, string Category)
        {
            try
            {
                string feedUrl="";
                string filePath = "\\Data\\" + Company + ".xml";
                XDocument db = XDocument.Load(filePath);
                var q = from n in db.Descendants("News")
                        where n.Element("Category").Value == Category
                        select n;
                foreach (var item in q)
                {
                    feedUrl = item.Element("FeedURL").Value;
                    // one value only
                    break;
                }
                return feedUrl;
            }
            catch (Exception ex)
            {                
                Error.LogError(ex.Message.ToString());
                return null;
            }
        }

        /// <summary>
        /// Get XML Feed
        /// </summary>
        /// <param name="feedUrl"></param>
        /// <returns>XMl feed Stream</returns>
        public Stream GetXMLFeed(string feedUrl)
        {
            try
            {
                // Sync Call
                //HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(feedUrl);                
                //HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                //Stream responseStream = response.GetResponseStream();
                //return responseStream;

                // Async Call - Polling method
                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(feedUrl);
                IAsyncResult result = request.BeginGetResponse(null, null);
                while (!result.IsCompleted)
                {
                    // Do some work
                }

                HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
                return response.GetResponseStream(); 

            }
            catch (Exception ex)
            {
                Error.LogError(ex.Message.ToString());
                return null;
            }
        }

        /// <summary>
        /// Get List of Companies
        /// </summary>
        /// <returns>Generic List</returns>
        public List<object> GetNewsCompanyCollection()
        {
            try
            {
                string filePath = "\\Data\\NewsCompany" + ".xml";
                XDocument db = XDocument.Load(filePath);
                var q = from c in db.Descendants("Company")
                        select c;
                List<object> newsCompanyCollection = new List<object>();
                foreach (var item in q)
                {
                    newsCompanyCollection.Add(item.Element("Name").Value);
                }
                return newsCompanyCollection;
            }
            catch (Exception ex)
            {
                
                Error.LogError(ex.Message.ToString());
                return null;
            }
        }

        /// <summary>
        /// Get List of Categories
        /// </summary>
        /// <returns>Generic List Object</returns>
        public List<object> GetNewsCategoryCollection()
        {
            try
            {
                string filePath = "\\Data\\NewsCategory" + ".xml";
                XDocument db = XDocument.Load(filePath);
                var q = from c in db.Descendants("Category")
                        select c;
                List<object> newsCompanyCollection = new List<object>();
                foreach (var item in q)
                {
                    newsCompanyCollection.Add(item.Element("Name").Value);
                }
                return newsCompanyCollection;
            }
            catch (Exception ex)
            {

                Error.LogError(ex.Message.ToString());
                return null;
            }
        }
        #region IDisposable Members

        void IDisposable.Dispose()
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}
